/**
 * @Project Name :  als-rpc
 * @Package Name :  com.alvis.transfer
 * @Description :  TODO
 * @author :  Alvis
 * @Creation Date:  2018-07-03 8:45 AM
 * @ModificationHistory Who    When    What
 * --------  ---------  --------------------------
 */
package com.alvis.transfer;

import com.alvis.container.RpcBean;
import com.alvis.container.spring.SpringBeanImpl;
import com.alvis.utilities.ClassHelper;
import com.alvis.utilities.Serialize;
import com.alvis.utilities.SerializeImpl;
import com.alvis.container.spring.SpringApplication;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;

/**
 * @author :  Alvis
 * @Description :  TODO
 * @Creation Date:  2018-07-03 8:45 AM
 */
public class ServerHandler extends ChannelInboundHandlerAdapter {

    private final static Logger logger = LoggerFactory.getLogger(ServerHandler.class);

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        logger.info("rpc server receive a client");
        try {
            RpcRequest rpcRequest = (RpcRequest) msg;
            RpcBean springBean = new SpringBeanImpl(SpringApplication.getAnnotationApplicationContext());
            Object instant = springBean.getBeanByName(rpcRequest.getServiceName());
            Method method = instant.getClass().getDeclaredMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
            Object invokeResult = method.invoke(instant, rpcRequest.getArgs());
            ctx.writeAndFlush(new RpcResponse(rpcRequest.getServiceName(), invokeResult));
        } finally {
            ReferenceCountUtil.release(msg);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.info(cause.getMessage());
        ctx.close();
        ctx.disconnect();
    }


}
